package com.apchernykh.rozhlasapp.services;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URL;
import java.net.URLConnection;
import java.text.SimpleDateFormat;
import java.util.Locale;

import com.apchernykh.ceskyrozhlas.basic.R;
import com.apchernykh.rozhlasapp.RozhlasAppActivity;
import com.apchernykh.rozhlasapp.utils.ConditionalLog;
import com.apchernykh.types.Show;

import android.app.IntentService;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.os.Environment;
import android.os.Parcelable;
import android.support.v4.app.NotificationCompat;


public class PodcastDownloadService extends IntentService {

	private static final String NOTIF_CONTENT = "SHOW_DESCR";
	final static private SimpleDateFormat mFilesystemDateFormat = new SimpleDateFormat(
			"d MMM HH mm", Locale.getDefault());

	public static Intent createDownloadIntent(Context iApplicationContext,
			Show iShow) {
		Intent aNotificationIntent = new Intent(iApplicationContext, PodcastDownloadService.class);
		aNotificationIntent.putExtra(NOTIF_CONTENT, iShow);
		return aNotificationIntent;
	}

	public PodcastDownloadService() {
		super("BackgroundDownloadService");
		// TODO Auto-generated constructor stub
	}

	public PodcastDownloadService(String iName) {
		super(iName);
		// TODO Auto-generated constructor stub
	}

	@Override
	protected void onHandleIntent(Intent iIntent) {
		final Parcelable aContentDescr = iIntent
				.getParcelableExtra(NOTIF_CONTENT);
		if (aContentDescr == null || !(aContentDescr instanceof Show)) {
			return;
		}
		final Show aShow = (Show) aContentDescr;
		final int aNotificationID = 1;
		NotificationManager mNotifyManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);

		String destinationDir = this.getText(R.string.app_name) + "/podcasty";
		//recommended filename length limitation is 127. Real limitation is unknown.
		final int maxFileNameLength = 120;

		String destinationFilename = aShow.getTitle() + " "
				+ mFilesystemDateFormat.format(aShow.getDate())+" (" + aShow.getDescription()+ ")";
		if(destinationFilename.length() > maxFileNameLength)
		{
		    destinationFilename = destinationFilename.substring(0, maxFileNameLength-4) + "...)";
		}
		destinationFilename +=  ".mp3";
		destinationFilename = destinationFilename.replaceAll("[\\?\\*\\\\<>:+\\[\\]\\|/\'\"]", " ");

		try {
			final URL url = new URL(aShow.getUrl());
			final URLConnection urlConnection = url.openConnection();
			urlConnection.connect();
			final int aFileSize = urlConnection.getContentLength();

			NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(
					this);

			mBuilder.setContentTitle(aShow.getTitle())
					.setContentText(aShow.getDescription())
					.setSmallIcon(R.drawable.ic_cro_logo_big)
					.setContentIntent(
							PendingIntent.getActivity(getBaseContext()
									.getApplicationContext(), 0, new Intent(
									getBaseContext().getApplicationContext(),
									RozhlasAppActivity.class),
									PendingIntent.FLAG_UPDATE_CURRENT));

			
			int aDownloadedBytes = 0;
			
			final File outdir = new File(
					Environment.getExternalStorageDirectory(),
					destinationDir);
			outdir.mkdirs();
			final File file = new File(outdir, destinationFilename);
			final BufferedInputStream aInputStream = new BufferedInputStream(
					urlConnection.getInputStream());
			final BufferedOutputStream aOutputStream = new BufferedOutputStream  (
					new FileOutputStream(file));
			
			int aReceivedBytesCount = 0;

			byte[] aDownloadBuffer = new byte[Math.max(aFileSize/110, 4096)];
			long aLastProgressUpdate = System.currentTimeMillis();
			while( ( aReceivedBytesCount = aInputStream.read(aDownloadBuffer) ) != -1 ) {
				aDownloadedBytes+=aReceivedBytesCount;
				aOutputStream.write( aDownloadBuffer, 0, aReceivedBytesCount );
			    final long aCurrentTimeStamp = System.currentTimeMillis();
			    if(aCurrentTimeStamp > aLastProgressUpdate + 789)
			    {
			    	aLastProgressUpdate = aCurrentTimeStamp;
					mBuilder.setProgress(aFileSize, aDownloadedBytes, false);
					mBuilder.setContentText(String.valueOf((int)(((double )aDownloadedBytes*100.0)/(double)aFileSize))+"%, "+aShow.getDescription());
					mNotifyManager.notify(aNotificationID, mBuilder.build());
			    }
			}

			aOutputStream.close();
			aInputStream.close();
		} catch (IOException e1) {
			// TODO Auto-generated catch block
			ConditionalLog.e(this.toString(),
					"Unable to save podcast.", e1);
			e1.printStackTrace();
		}

		mNotifyManager.cancel(aNotificationID);
	}
}
